﻿using System;
using System.Drawing;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Windows.Forms;
using System.Xml.Serialization;
using RPGMapa.Controls;
using RPGMapa.Data;
using RPGMapa.Forms;
using RPGMapa.Tools;

namespace RPGMapa
{
    public partial class GUI
    {
        private void CreateMap()
        {
            NewMap nm = new NewMap();
            nm.ShowDialog();
            if (nm.Result == null)
            {
                mapa = new Map();
            }
            else
            {
                mapa = nm.Result;

            }
            mapArea1.Create(mapa);
        }
        private void SaveMap()
        {
            IFormatter f = new BinaryFormatter();
            using (Stream s = new MemoryStream())
            {
                f.Serialize(s, mapa);

                s.Seek(0, SeekOrigin.Begin);
                using (SaveFileDialog sfd = new SaveFileDialog())
                {
                    sfd.Filter = "(*.tcmap)|*.tcmap";
                    if (sfd.ShowDialog() == DialogResult.OK)
                    {
                        using (FileStream file = File.Create(sfd.FileName))
                        {
                            s.CopyTo(file);
                        }
                    }
                }
            }
        }
        private void LoadMap()
        {
            using (OpenFileDialog ofd = new OpenFileDialog())
            {
                ofd.Filter = "(*.tcmap)|*.tcmap";
                ofd.Title = "Open serializated file";
                if (ofd.ShowDialog() == DialogResult.OK)
                {
                    using (FileStream file = File.Open(ofd.FileName, FileMode.Open))
                    {
                        IFormatter f = new BinaryFormatter();
                        mapa = (Map)f.Deserialize(file);
                        mapArea1.Create(mapa);

                        previewBox.Image = mapa.Layer;
                    }
                }
            }
        }
        private void ImportMap()
        {
            Map loadedMap;
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = "Game Map (*.gamemap)|*.gamemap";
            ofd.Title = "Load header file";
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                loadedMap = MapIO.Decode(File.ReadAllText(ofd.FileName));

                ofd.Title = "Load map Image";
                ofd.Filter = "Images (*.BMP;*.PNG;*.JPG;*.GIF)|*.BMP;*.PNG;*.JPG;*.GIF|" +
                                "All files (*.*)|*.*"; ;
                if (ofd.ShowDialog() == DialogResult.OK)
                {
                    loadedMap.Layer = (Bitmap)Image.FromFile(ofd.FileName);
                    mapArea1.Create(loadedMap);
                    mapa = loadedMap;
                }
            }
        }
        private void ExportMap()
        {
            SaveFileDialog sfd = new SaveFileDialog();

            if (sfd.ShowDialog() == DialogResult.OK)
            {
                mapa.Layer.Save(sfd.FileName + ".png");
                File.WriteAllText(sfd.FileName + ".gamemap", MapIO.Encode(mapa));
            }
        }


        private void GenerateParams(MouseEventArgs e, out Size s, out Vector2 pos)
        {
            Size size = new Size(
                MapCTRL.Width / MapCTRL.TileCapacity.X,
                MapCTRL.Height / MapCTRL.TileCapacity.Y);
            Vector2 position = new Vector2 // in TileSpace
                ((e.X - e.X % size.Width) / size.Width,
                 (e.Y - e.Y % size.Height) / size.Height);
            position.X = (position.X < 1) ? 0 : (position.X > MapCTRL.TileCapacity.X - 1) ? MapCTRL.TileCapacity.X - 1 : position.X;
            position.Y = (position.Y < 1) ? 0 : (position.Y > MapCTRL.TileCapacity.Y - 1) ? MapCTRL.TileCapacity.Y - 1 : position.Y;

            s = size;
            pos = position;
        }

        private void MapClick(object s, MouseEventArgs e)
        {
            Size size;
            Vector2 position;
            GenerateParams(e, out size, out position);

            if (position != lastPos)
            {
                tool.MouseClick(tilesetPicker1.SelectedTile, size, position, MapCTRL);
                lastPos = position;
            }
        }
        private void MapMove(object s, MouseEventArgs e)
        {
            Size size;
            Vector2 position;
            GenerateParams(e, out size, out position);

            if (position != lastPos)
            {
                tool.MouseMove(tilesetPicker1.SelectedTile, size, position, MapCTRL);
                lastPos = position;
            }
        }
        private void MapDown(object s, MouseEventArgs e)
        {
            Size size;
            Vector2 position;
            GenerateParams(e, out size, out position);

            if (position != lastPos)
            {
                tool.MouseDown(tilesetPicker1.SelectedTile, size, position, MapCTRL);
                lastPos = position;
            }
        }
        private void MapUp(object s, MouseEventArgs e)
        {
            Size size;
            Vector2 position;
            GenerateParams(e, out size, out position);

            if (position != lastPos)
            {
                tool.MouseUp(tilesetPicker1.SelectedTile, size, position, MapCTRL);
                lastPos = position;
            }
        }
    }
}
